home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / tools / czesc_3 / multiuser / src / library / log.c < prev    next >
C/C++ Source or Header  |  1995-05-23  |  22KB  |  512 lines

  1. /************************************************************
  2. * MultiUser - MultiUser Task/File Support System                                *
  3. * ---------------------------------------------------------     *
  4. * Login Access Management                                                                                               *
  5. * ---------------------------------------------------------     *
  6. * © Copyright 1993-1994 Geert Uytterhoeven                                              *
  7. * All Rights Reserved.                                                                                                  *
  8. ************************************************************/
  9.  
  10.  
  11. #include <proto/exec.h>
  12. #include <proto/dos.h>
  13. #include <proto/utility.h>
  14. #include <proto/reqtools.h>
  15. #include <exec/execbase.h>
  16. #include <exec/alerts.h>
  17. #include <dos/dos.h>
  18. #include <dos/var.h>
  19. #include <dos/datetime.h>
  20. #include <utility/tagitem.h>
  21. #include <libraries/reqtools.h>
  22. #include <string.h>
  23.  
  24. #include "Log.h"
  25. #include "Misc.h"
  26. #include "Config.h"
  27. #include "Locale.h"
  28. #include "LibHeader.h"
  29. #include "UserInfo.h"
  30. #include "Task.h"
  31. #include "Server.h"
  32. #include "Monitor.h"
  33.  
  34.  
  35.         /*
  36.          *              Static Routines
  37.          */
  38.  
  39. static void myfputs(BPTR file, STRPTR str);
  40. static BOOL myfgets(BPTR file, STRPTR str, ULONG len);
  41. static struct muPrivUserInfo *LoginRequest(struct muTags *tags, BOOL failallowed, BOOL nopasswd, struct LocaleInfo *li);
  42. static BOOL GetUserIDGUI(STRPTR userid, STRPTR version, STRPTR hostname, STRPTR scrname, struct LocaleInfo *li);
  43. static BOOL GetPasswordGUI(STRPTR password, STRPTR scrname, struct LocaleInfo *li);
  44. static BOOL GetUserIDCon(STRPTR userid, STRPTR version, STRPTR hostname, BPTR input, BPTR output,
  45.                                                                  int *retry, struct LocaleInfo *li);
  46. static BOOL GetPasswordCon(STRPTR password, BPTR input, BPTR output, struct LocaleInfo *li);
  47. static BOOL CheckPassword(STRPTR uid);
  48.  
  49.  
  50.         /*
  51.          *              Support Functions
  52.          */
  53.  
  54. static void __inline myfputs(BPTR file, STRPTR str)
  55. {
  56.         Write(file, str, strlen(str));
  57. }
  58.  
  59.  
  60. static BOOL __inline myfgets(BPTR file, STRPTR str, ULONG len)
  61. {
  62.         LONG readlen;
  63.  
  64.         readlen = Read(file, str, len);
  65.         if (readlen > 1) {
  66.                 str[readlen-1] = '\0';
  67.                 return(TRUE);
  68.         } else {
  69.                 str[0] = '\0';
  70.                 return(FALSE);
  71.         }
  72. }
  73.  
  74.  
  75.         /*
  76.          *              Logout and Restore the Previous User
  77.          *
  78.          *              Public Library Function
  79.          *
  80.          *              If there are no users left for the task, a login requester will
  81.          *              appear.
  82.          */
  83.  
  84.  
  85. ULONG __asm __saveds muLogoutA(register __a0 struct TagItem *taglist)
  86. {
  87.         struct muExtOwner *xuser;
  88.         ULONG user;
  89.         struct muPrivUserInfo *info;
  90.         char day[LEN_DATSTRING];
  91.         char date[LEN_DATSTRING];
  92.         char time[LEN_DATSTRING];
  93. #define LASTLOGINSIZE (3*LEN_DATSTRING+2)
  94.         char lastlogin[LASTLOGINSIZE+1];
  95.                 /* V39+: use lastlogin[LASTLOGINSIZE] */
  96.         char buffer[256];
  97.         BPTR file, dir, seglist;
  98.         struct DateTime dt;
  99.         struct FileInfoBlock *fib;
  100.         STRPTR args[6];
  101.         struct muTags tags;
  102.         struct Segment *seg;
  103.         BOOL neverloggedin = TRUE;
  104.         int i;
  105.         char *fmt;
  106.         BOOL nobody;
  107.         struct LocaleInfo li;
  108.  
  109.         if (!InterpreteTagList(taglist, &tags))
  110.                 return(muOWNER_NOBODY);
  111.  
  112.         tags.UserID = tags.Password = NULL;
  113.         tags.NoLog = FALSE;
  114.  
  115.         OpenLoc(&li);
  116.  
  117.         do {
  118.                 if (tags.Global)
  119.                         nobody = !PopTaskLevelDetach(tags.Task);
  120.                 else
  121.                         nobody = !PopTaskDetach(tags.Task);
  122.         } while (tags.All && !nobody);
  123.         user = GetTaskOwner(tags.Task);
  124.         if (nobody && !tags.Quiet)
  125.                 if (info = LoginRequest(&tags, FALSE, FALSE, &li)) {
  126.                         PushTask(SysBase->ThisTask, &RootExtOwner);
  127.  
  128.                         xuser = muUserInfo2ExtOwner(info);
  129.                         SetVar("Home", info->Pub.HomeDir, -1, GVF_LOCAL_ONLY);
  130.                         if (fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL)) {
  131.                                 if (dir = Lock(info->Pub.HomeDir, ACCESS_READ)) {
  132.                                         if (Examine(dir, fib) && (fib->fib_DirEntryType > 0)) {
  133.                                                 if (NameFromLock(dir, buffer, 256))
  134.                                                         SetCurrentDirName(buffer);
  135.                                                 dir = CurrentDir(dir);
  136.                                         }
  137.                                         UnLock(dir);
  138.                                 }
  139.                                 FreeDosObject(DOS_FIB, fib);
  140.                         }
  141.                         muFreeUserInfo(info);
  142.  
  143.                         if (file = Open(muLastLogin_FileName, MODE_OLDFILE)) {
  144.                                 if (FGets(file, lastlogin, LASTLOGINSIZE))
  145.                                         neverloggedin = FALSE;
  146.                                 Close(file);
  147.                         }
  148.                         dt.dat_Format = FORMAT_DOS;
  149.                         dt.dat_Flags = NULL;
  150.                         DateStamp(&dt.dat_Stamp);
  151.                         dt.dat_StrDay = day;
  152.                         dt.dat_StrDate = date;
  153.                         dt.dat_StrTime = time;
  154.                         DateToStr(&dt);
  155.                         args[0] = day;
  156.                         args[1] = date;
  157.                         args[2] = time;
  158.                         if (file = Open(muLastLogin_FileName, MODE_NEWFILE)) {
  159.                                 VFPrintf(file, "%s %s %s\n", (LONG *)args);
  160.                                 Close(file);
  161.                         }
  162.                         if (!neverloggedin) {
  163.                                 args[3] = lastlogin;
  164.                                 args[4] = "";
  165.                                 args[5] = "";
  166.                                 for (i = 0; lastlogin[i] && (lastlogin[i] != ' '); i++);
  167.                                 if (lastlogin[i]) {
  168.                                         lastlogin[i++] = '\0';
  169.                                         while (lastlogin[i] == ' ')
  170.                                                 i++;
  171.                                         args[4] = &lastlogin[i];
  172.                                         while (lastlogin[i] && (lastlogin[i] != ' '))
  173.                                                 i++;
  174.                                         if (lastlogin[i]) {
  175.                                                 lastlogin[i++] = '\0';
  176.                                                 while (lastlogin[i] == ' ')
  177.                                                         i++;
  178.                                                 args[5] = &lastlogin[i];
  179.                                                 while (lastlogin[i] && (lastlogin[i] != ' ') &&
  180.                                                                  (lastlogin[i] != '\n'))
  181.                                                         i++;
  182.                                                 lastlogin[i] = '\0';
  183.                                         }
  184.                                 }
  185.                         }
  186.  
  187.                         PopTask(SysBase->ThisTask);
  188.  
  189.                         if (neverloggedin)
  190.                                 fmt = GetLocS(&li,MSG_FIRSTLOGIN);
  191.                         else
  192.                                 fmt = GetLocS(&li,MSG_LASTLOGIN);
  193.  
  194.                         if (tags.Graphical) {
  195.                                 if (muBase->Config.Flags & muCFGF_LastLoginReq)
  196.                                         rtEZRequestTags(fmt, GetLocS(&li,MSG_OK), NULL, args,
  197.                                                                                  RTEZ_Flags, EZREQF_CENTERTEXT,
  198.                                                                                  RT_PubScrName, tags.PubScrName,
  199.                                                                                  RT_ReqPos, REQPOS_CENTERSCR,
  200.                                                                                  RT_LockWindow, TRUE,
  201.                                                                                  TAG_DONE);
  202.                         } else {
  203.                                 FPuts(tags.Output, "\n");
  204.                                 VFPrintf(tags.Output, fmt, (LONG *)args);
  205.                                 FPuts(tags.Output, "\n");
  206.                                 Flush(tags.Output);
  207.                         }
  208.  
  209.                         if (tags.Global)
  210.                                 PushTaskLevel(tags.Task, xuser);
  211.                         else
  212.                                 PushTask(tags.Task, xuser);
  213.  
  214.                         if ((muBase->Config.Flags & muCFGF_Profile) &&
  215.                                  (dir = (BPTR)SendServerPacket(muSAction_ConfigDirLock, NULL,
  216.                                                                                                                  NULL, NULL, NULL))) {
  217.                                 dir = CurrentDir(dir);
  218.                                 if (file = Lock(muProfile_FileName, ACCESS_READ)) {
  219.                                         Forbid();
  220.                                         if (seg = FindSegment("Execute", NULL, NULL))
  221.                                                 seg->seg_UC++;
  222.                                         Permit();
  223.                                         if (seg)
  224.                                                 seglist = seg->seg_Seg;
  225.                                         else
  226.                                                 seglist = NewLoadSeg("C:Execute", NULL);
  227.                                         if (seglist) {
  228.                                                 RunCommand(seglist, 4000, muProfile_FileName "\n",
  229.                                                                           strlen(muProfile_FileName "\n"));
  230.                                                 if (!seg)
  231.                                                         UnLoadSeg(seglist);
  232.                                         }
  233.                                         if (seg) {
  234.                                                 Forbid();
  235.                                                 seg->seg_UC--;
  236.                                                 Permit();
  237.                                         }
  238.                                         UnLock(file);
  239.                                 }
  240.                                 UnLock(CurrentDir(dir));
  241.                         }
  242.                         user = muExtOwner2ULONG(xuser);
  243.                         muFreeExtOwner(xuser);
  244.                 } else
  245.                         Die(NULL, AN_Unknown | AG_BadParm);
  246.  
  247.         CloseLoc(&li);
  248.  
  249.         return(user);
  250. }
  251.  
  252.  
  253.         /*
  254.          *              Login to the System and Add the User to the Task
  255.          *
  256.          *              Public Library Function
  257.          */
  258.  
  259.  
  260. ULONG __asm __saveds muLoginA(register __a0 struct TagItem *taglist)
  261. {
  262.         struct muExtOwner *xuser;
  263.         struct muPrivUserInfo *info;
  264.         struct muTags tags;
  265.         BOOL res;
  266.         struct LocaleInfo li;
  267.  
  268.         if (!InterpreteTagList(taglist, &tags) || (tags.Password && !tags.UserID))
  269.                 return(muOWNER_NOBODY);
  270.  
  271.         xuser = GetTaskExtOwner(SysBase->ThisTask);
  272.         if (!tags.Own)
  273.         {                 /*  { by fpetzold */
  274.                 OpenLoc(&li);
  275.                 if (info = LoginRequest(&tags, TRUE, muGetRelationshipA(xuser, NULL, NULL) & muRelF_ROOT_UID, &li)) {
  276.                         muFreeExtOwner(xuser);
  277.                         xuser = muUserInfo2ExtOwner(info);
  278.                         muFreeUserInfo(info);
  279.                 } else {
  280.                         muFreeExtOwner(xuser);
  281.                         return(muOWNER_NOBODY);
  282.                 }
  283.                 CloseLoc(&li);
  284.         }                 /* } by fpetzold */
  285.         if (tags.Global)
  286.                 res = PushTaskLevel(tags.Task, xuser);
  287.         else
  288.                 res = PushTask(tags.Task, xuser);
  289.         muFreeExtOwner(xuser);
  290.  
  291.         return(GetTaskOwner(tags.Task));
  292. }
  293.  
  294.  
  295.         /*
  296.          *              Request the User for a Login
  297.          */
  298.  
  299. static struct muPrivUserInfo *LoginRequest(struct muTags *tags, BOOL failallowed, BOOL nopasswd, struct LocaleInfo *li)
  300. {
  301.         BOOL ret;
  302.         char version[8];
  303.         char hostname[32];
  304.         char uidbuf[muUSERIDSIZE];
  305.         char pwdbuf[muPASSWORDSIZE];
  306.         STRPTR userid, password;
  307.         struct muPrivUserInfo *info = NULL;
  308.         int retry = 0, i;
  309.  
  310.         if (GetVar("Kickstart", version, 8, GVF_GLOBAL_ONLY) == -1)
  311.                 strcpy(version, "?");
  312.         if (GetVar("HostName", hostname, 32, GVF_GLOBAL_ONLY) == -1)
  313.                 strcpy(hostname, "?");
  314.         else {
  315.                 for (i = 0; hostname[i] && (hostname[i] != '.'); i++);
  316.                 if (hostname[i] == '.')
  317.                         hostname[i] = '\0';
  318.         }
  319.  
  320.         do {
  321.                 if (tags->UserID)
  322.                         userid = tags->UserID;
  323.                 else {
  324.                         userid = uidbuf;
  325.                         do {
  326.                                 memset(uidbuf, '\0', sizeof(uidbuf));
  327.                                 if (tags->Graphical)
  328.                                         ret = GetUserIDGUI(uidbuf, version, hostname,
  329.                                                                                          tags->PubScrName, li);
  330.                                 else
  331.                                         ret = GetUserIDCon(uidbuf, version, hostname, tags->Input,
  332.                                                                                          tags->Output, &retry, li);
  333.                                 if (!ret && failallowed)
  334.                                         return(NULL);
  335.                         } while (!ret);
  336.                 }
  337.                 if (tags->Password)
  338.                         password = tags->Password;
  339.                 else {
  340.                         password = pwdbuf;
  341.                         memset(pwdbuf, '\0', sizeof(pwdbuf));
  342.                         if (!nopasswd && CheckPassword(userid)) {
  343.                                 if (tags->Graphical)
  344.                                         ret = GetPasswordGUI(pwdbuf, tags->PubScrName, li);
  345.                                 else
  346.                                         ret = GetPasswordCon(pwdbuf, tags->Input, tags->Output, li);
  347.                                 if (!ret)
  348.                                         if (failallowed)
  349.                                                 return(NULL);
  350.                                         else
  351.                                                 password = NULL;
  352.                         }
  353.                 }
  354.                 if (userid && password) {
  355.                         info = (struct muPrivUserInfo *)SendServerPacket(muSAction_CheckUser, (LONG)userid,
  356.                                                                                                                                                          (LONG)password, (LONG)nopasswd,
  357.                                                                                                                                                          (LONG)tags->NoLog);
  358.                         memset(pwdbuf, '\0', sizeof(pwdbuf));
  359.                         if (!info)
  360.                                 if (failallowed)
  361.                                         return(NULL);
  362.                                 else if (tags->Graphical)
  363.                                         rtEZRequestTags(GetLocS(li,MSG_LOGINFAIL_GUI), 
  364.                                                                                  GetLocS(li,MSG_OK), NULL, NULL,
  365.                                                                                  RTEZ_Flags, EZREQF_CENTERTEXT,
  366.                                                                                  RT_PubScrName, tags->PubScrName,
  367.                                                                                  RT_ReqPos, REQPOS_CENTERSCR,
  368.                                                                                  RT_LockWindow, TRUE,
  369.                                                                                  TAG_DONE);
  370.                                 else
  371.                                         myfputs(tags->Output, GetLocS(li,MSG_LOGINFAIL_CON));
  372.                 }
  373.         } while (!info);
  374.         return(info);
  375. }
  376.  
  377.  
  378.         /*
  379.          *              Ask the User for his UserID (Graphical User Interface version)
  380.          */
  381.  
  382. static BOOL GetUserIDGUI(STRPTR userid, STRPTR version, STRPTR hostname, STRPTR scrname, struct LocaleInfo *li)
  383. {
  384.         STRPTR args[2];
  385.  
  386.         args[0] = version;
  387.         args[1] = hostname;
  388.         return((BOOL)rtGetString(userid, muUSERIDSIZE-1, GetLocS(li,MSG_LOGINREQ_GUI),
  389.                                                                          NULL, RTGS_TextFmt, GetLocS(li,MSG_LOGINPROMPT_GUI),
  390.                                                                                          RTGS_TextFmtArgs, args,
  391.                                                                                          RTGS_Flags, GSREQF_CENTERTEXT,
  392.                                                                                          RT_PubScrName, scrname,
  393.                                                                                          RT_ReqPos, REQPOS_CENTERSCR,
  394.                                                                                          RT_LockWindow, TRUE,
  395.                                                                                          TAG_DONE));
  396. }
  397.  
  398.  
  399.         /*
  400.          *              Ask the User for his Password (Graphical User Interface version)
  401.          */
  402.  
  403. static BOOL GetPasswordGUI(STRPTR password, STRPTR scrname, struct LocaleInfo *li)
  404. {
  405.         return((BOOL)rtGetString(password, muPASSWORDSIZE-1,
  406.                                                                          GetLocS(li,MSG_LOGINREQ_GUI), NULL,
  407.                                                                          RTGS_TextFmt, GetLocS(li,MSG_PASSWDPROMPT_GUI),
  408.                                                                          RTGS_Invisible, TRUE,
  409.                                                                          RTGS_AllowEmpty, TRUE,
  410.                                                                          RTGS_Flags, GSREQF_CENTERTEXT,
  411.                                                                          RT_PubScrName, scrname,
  412.                                                                          RT_ReqPos, REQPOS_CENTERSCR,
  413.                                                                          RT_LockWindow, TRUE,
  414.                                                                          TAG_DONE));
  415. }
  416.  
  417.  
  418.         /*
  419.          *              Ask the User for his UserID (Standard Console I/O version)
  420.          */
  421.  
  422. static BOOL GetUserIDCon(STRPTR userid, STRPTR version, STRPTR hostname, BPTR input, BPTR output,
  423.                                                                  int *retry, struct LocaleInfo *li)
  424. {
  425.         STRPTR args[2];
  426.         BOOL ret;
  427.  
  428.         args[0] = version;
  429.         args[1] = hostname;
  430.         if (!*retry) {
  431.                 VFPrintf(output, GetLocS(li,MSG_LOGINREQ_CON), (LONG *)args);
  432.                 Flush(output);
  433.         }
  434.         myfputs(output, GetLocS(li,MSG_LOGINPROMPT_CON));
  435.         myfputs(output," ");
  436.         ret = myfgets(input, userid, muUSERIDSIZE);
  437.         if (ret)
  438.                 *retry = (*retry+1) % 4;
  439.         else
  440.                 *retry = 0;
  441.         return(ret);
  442. }
  443.  
  444.  
  445.         /*
  446.          *              Ask the User for his Password (Standard Console I/O version)
  447.          */
  448.  
  449. static BOOL GetPasswordCon(STRPTR password, BPTR input, BPTR output, struct LocaleInfo *li)
  450. {
  451.         BOOL done;
  452.         ULONG len;
  453.         char buffer;
  454.  
  455.         myfputs(output, GetLocS(li,MSG_PASSWDPROMPT_CON));
  456.         myfputs(output, " ");
  457.         done = FALSE;
  458.         len = 0;
  459.         SetMode(input, 1);
  460.         do {
  461.                 Read(input, &buffer, 1);
  462.                 switch(buffer) {
  463.                         case    '\b':
  464.                                 if (len) {
  465.                                         FPutC(output, '\b');
  466.                                         Flush(output);
  467.                                         len--;
  468.                                 }
  469.                                 break;
  470.  
  471.                         case    '\n':
  472.                         case    '\r':
  473.                                 done = TRUE;
  474.                                 break;
  475.  
  476.                         default:
  477.                                 if ((len < muPASSWORDSIZE-1) && ((buffer & 0x7f) > 31)
  478.                                          && (buffer != 127)) {
  479.                                         FPutC(output, ' ');
  480.                                         password[len++] = buffer;
  481.                                 } else
  482.                                         FPutC(output, 7);
  483.                                 Flush(output);
  484.                                 break;
  485.                 }
  486.         } while (!done);
  487.         password[len] = '\0';
  488.         SetMode(input, 0);
  489.         myfputs(output, "\n");
  490.         return(TRUE);
  491. }
  492.  
  493.  
  494.         /*
  495.          *              Check whether a User has a Password or not
  496.          */
  497.  
  498. static BOOL CheckPassword(STRPTR userid)
  499. {
  500.         struct muPrivUserInfo *info;
  501.         BOOL pwd = TRUE;
  502.  
  503.         if (info = muAllocUserInfo()) {
  504.                 strncpy(info->Pub.UserID, userid, muUSERIDSIZE-1);
  505.                 info->Pub.UserID[muUSERIDSIZE-1] = '\0';
  506.                 if (SendServerPacket(muSAction_GetUserInfo, (LONG)info, muKeyType_UserID, NULL, NULL))
  507.                         pwd = info->Password;
  508.                 muFreeUserInfo(info);
  509.         }
  510.         return(pwd);
  511. }
  512.